package com.sec.android.app.myfiles.dialog;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.DownloadManager;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.widget.Toast;

import com.sec.android.app.myfiles.R;
import com.sec.android.app.myfiles.facade.MyFilesFacade;
import com.sec.android.app.myfiles.facade.cmd.DeleteRecordCmd.OperationProgress;
import com.sec.android.app.myfiles.fragment.AbsMyFilesFragment;
import com.sec.android.app.myfiles.log.Log;
import com.sec.android.app.myfiles.log.SamsungAnalyticsLog;
import com.sec.android.app.myfiles.module.abstraction.FileRecord;
import com.sec.android.app.myfiles.module.download.DownloadFileRecord;
import com.sec.android.app.myfiles.module.download.DownloadFileRecord.DownloadType;
import com.sec.android.app.myfiles.provider.DbTableInfo;
import com.sec.android.app.myfiles.provider.DbTableInfo.COLUMN_ID;
import com.sec.android.app.myfiles.util.UiUtils;

import java.util.ArrayList;

/**
 * <pre>
 * Dialog class for ask to user delete or not.
 * Response Activity.RESULT_OK or Activity.RESULT_CANCELED
 * </pre>
 *
 * @author jae.bae
 */
public class ConfirmNotExistFileDialog extends DialogFragment {
    private DownloadFileRecord mRecord;
    private AbsMyFilesFragment mFragment;

    public static ConfirmNotExistFileDialog getInstance(DownloadFileRecord record, AbsMyFilesFragment fragment) {
        ConfirmNotExistFileDialog ret = new ConfirmNotExistFileDialog();
        ret.setRecord(record, fragment);
        return ret;
    }

    private void setRecord(DownloadFileRecord record, AbsMyFilesFragment fragment) {
        mRecord = record;
        mFragment = fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        DialogFragmentUtils.setTargetFragment(this);
        super.onSaveInstanceState(outState);
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        String title = mFragment.context().getResources().getString(R.string.cannot_open_file);
        String msg = mFragment.context().getResources().getString(R.string.delete_message_for_other_history);
        msg = String.format(mFragment.context().getResources().getString(R.string.delete_message_for_downloads), mRecord.getName());

        if (!mRecord.exists(mFragment.context()) && isReDownloadable()) {
            title = mFragment.context().getResources().getString(R.string.unable_to_open_file);
            msg = mFragment.context().getResources().getString(R.string.download_history_message);
            msg = String.format(mFragment.context().getResources().getString(R.string.downloads_message), mRecord.getName());
        }

        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getActivity())
                .setTitle(title)
                .setMessage(msg)
                .setNegativeButton(R.string.menu_remove, mOnRemoveListener).setNeutralButton(R.string.cancel, mOnCancelListener);

        if (isReDownloadable()) {
            dialogBuilder.setPositiveButton(R.string.download, mOnDownloadListener);
        }

        AlertDialog dialog = dialogBuilder.create();
        dialog.show();
        dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(UiUtils.isNetworkOn(getActivity()));

        return dialog;
    }

    private OnClickListener mOnDownloadListener = new OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            SamsungAnalyticsLog.sendLog(SamsungAnalyticsLog.ScreenPath.FROM_INTERNET, SamsungAnalyticsLog.Event.DOWNLOAD, null);
            requestDownload(mRecord);
        }
    };

    private OnClickListener mOnRemoveListener = new OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            Context context = mFragment.context();
            if (context != null) {
                ArrayList<FileRecord> arr = new ArrayList<>();
                arr.add(mRecord);
                MyFilesFacade.deleteRecord(mFragment.getProcessId(), context, mFragment, arr, OperationProgress.DO_OPERATE);
                SamsungAnalyticsLog.sendLog(SamsungAnalyticsLog.ScreenPath.FROM_INTERNET, SamsungAnalyticsLog.Event.DELETE, null);
            }
        }
    };

    private OnClickListener mOnCancelListener = new OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            SamsungAnalyticsLog.sendLog(SamsungAnalyticsLog.ScreenPath.FROM_INTERNET, SamsungAnalyticsLog.Event.CANCEL, null);
            dialog.dismiss();
        }
    };

    private void requestDownload(DownloadFileRecord record) {
        String name = record.getName();
        ContentResolver cr = getActivity().getContentResolver();
        DbTableInfo tableInfo = DbTableInfo.getInstance(FileRecord.StorageType.Downloads);

        if (tableInfo == null) {
            return;
        }

        try (Cursor cursor = cr.query(Uri.parse(tableInfo.getUri()), new String[]{
                        tableInfo.getColumnName(COLUMN_ID.SOURCE), tableInfo.getColumnName(COLUMN_ID.DESCRIPTION)},
                tableInfo.getColumnName(COLUMN_ID.ID) + " = " + record.getId(), null, null)) {

            Log.d(this, "tableInfo.getColumnName(COLUMN_ID.SOURCE) " + tableInfo.getColumnName(COLUMN_ID.SOURCE));
            Log.d(this, "tableInfo.getColumnName(COLUMN_ID.DESCRIPTION) " + tableInfo.getColumnName(COLUMN_ID.DESCRIPTION));
            Log.d(this, "tableInfo.getColumnName(COLUMN_ID.ID) " + tableInfo.getColumnName(COLUMN_ID.ID));
            Log.d(this, "record.getId() " + record.getId());

            String source;
            String description;

            if (cursor != null && cursor.getCount() > 0) {
                cursor.moveToFirst();
                source = record.getSource();
                description = record.getDescription();

                Log.d(this, "source " + source);

                final DownloadManager dm = (DownloadManager) mFragment.context().getSystemService(Context.DOWNLOAD_SERVICE);
                if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(source) && UiUtils.isNetworkOn(mFragment.context())) {
                    DownloadManager.Request request = new DownloadManager.Request(Uri.parse(source));
                    request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, name);
                    request.setDescription(description); // setDescription method doesn't generate the NPE even if description is NULL.
                    dm.enqueue(request);
                    dm.remove(record.getDownloadId());
                    Toast.makeText(mFragment.context(), R.string.download_pending, Toast.LENGTH_SHORT).show();
                }
            }

        }
    }

    @Override
    public void onDestroy() {
        dismissAllowingStateLoss();
        super.onDestroy();
    }

    /**
     * Shows dialog using commitAllowingStateLoss for committing
     * FragmentTransaction. The only danger is that state of the parent Fragment
     * might omit the fact, that the dialog has been shown.
     */
    public void showAllowingStateLoss(final FragmentManager fm, final String tag) {
        if (fm != null) {
            final FragmentTransaction t = fm.beginTransaction();
            t.add(this, tag);
            t.commitAllowingStateLoss();
        }
    }

    @Override
    public void dismissAllowingStateLoss() {
        try {
            super.dismissAllowingStateLoss();
        } catch (IllegalStateException e) {
            Log.e(this, "IllegalStateException:" + e.toString());
        }
    }

    private boolean isReDownloadable() {
        return mRecord.getDownloadType() == DownloadType.DOWNLOAD_BY_BROWSER && mRecord.getSource().startsWith("http");
    }
}
